package com.example.core.context;

import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

/**
 * @Author Peng Yisheng
 * @Date 2024/11/4 17:24
 * @Description 核心上下文基础类
 */
public class BaseContext implements IContext {

    protected final String protocol;  // 转发协议
    protected volatile int status = IContext.RUNNING;  // 上下文状态
    protected final ChannelHandlerContext nettyCtx;  // Netty上下文
    protected final Map<String, Object> attributes = new HashMap<>();  // 上下文参数集合
    protected Throwable throwable;  // 请求过程中发生的异常
    protected final boolean keepAlive;  // 是否保持长连接
    protected final AtomicBoolean requestReleased = new AtomicBoolean(false);  // 是否已经释放资源
    protected List<Consumer<IContext>> completedCallbacks;  // 存放回调函数的集合

    public BaseContext(String protocol, ChannelHandlerContext nettyCtx, boolean keepAlive) {
        this.protocol = protocol;
        this.nettyCtx = nettyCtx;
        this.keepAlive = keepAlive;
    }

    @Override
    public void running() {
        status = IContext.RUNNING;
    }

    @Override
    public void written() {
        status = IContext.WRITTEN;
    }

    @Override
    public void completed() {
        status = IContext.COMPLETED;
    }

    @Override
    public void terminated() {
        status = IContext.TERMINATED;
    }

    @Override
    public boolean isRunning() {
        return status == IContext.RUNNING;
    }

    @Override
    public boolean isWritten() {
        return status == IContext.WRITTEN;
    }

    @Override
    public boolean isCompleted() {
        return status == IContext.COMPLETED;
    }

    @Override
    public boolean isTerminated() {
        return status == IContext.TERMINATED;
    }

    @Override
    public String getProtocol() {
        return this.protocol;
    }

    @Override
    public Object getRequest() {
        return null;
    }

    @Override
    public Object getResponse() {
        return null;
    }

    @Override
    public Throwable getThrowable() {
        return this.throwable;
    }

    @Override
    public ChannelHandlerContext getNettyCtx() {
        return this.nettyCtx;
    }

    @Override
    public boolean isKeepAlive() {
        return this.keepAlive;
    }

    @Override
    public void setRule() {

    }

    @Override
    public void setResponse() {

    }

    @Override
    public void setThrowable(Throwable throwable) {
        this.throwable = throwable;
    }

    @Override
    public void setCompletedCallBack(Consumer<IContext> consumer) {
        if (completedCallbacks == null) {
            completedCallbacks = new ArrayList<>();
        }
        completedCallbacks.add(consumer);
    }

    @Override
    public void releaseRequest() {
        this.requestReleased.compareAndSet(false, true);
    }

    @Override
    public void invokeCompletedCallBack() {
        if (completedCallbacks == null) {
            completedCallbacks.forEach(call -> call.accept(this));
        }
    }

}
